`include "timescale.v"

module crc8 (
	input 		   reset, clk, enable, init,
	input  [7:0]   Data,
	output [7:0]   Crc,
	output 		   CrcErr,
	output 		   PreCrcErr
	);

// wire 	  [7:0]  CrcNext;
wire 	  [7:0]   CN;
reg 	  [7:0]   C;
assign 			  Crc 		  = C;

wire 	  [7:0]   D;
assign 			  D 		  = Data;

//when enable is 0, the CRC regs only shift left 8'bits each clk
assign 			  CN[7] 	  = (C[7] ^ D[0]) ^ (D[1] ^ C[6]) ^ (D[2] ^ C[5]);
assign 			  CN[6] 	  = (C[6] ^ D[1]) ^ (D[2] ^ C[5]) ^ (D[3] ^ C[4]);
assign 			  CN[5] 	  = (C[5] ^ D[2]) ^ (D[3] ^ C[4]) ^ (D[4] ^ C[3]);
assign 			  CN[4] 	  = (C[4] ^ D[3]) ^ (D[4] ^ C[3]) ^ (D[5] ^ C[2]);
								 
assign 			  CN[3] 	  = (C[3] ^ D[4]) ^ (D[5] ^ C[2]) ^ (D[6] ^ C[1] ^ D[0] ^ C[7]);
assign 			  CN[2] 	  = (C[2] ^ D[5]) ^ (D[6] ^ C[1] ^ D[0] ^ C[7]) ^ (D[7] ^ C[0] ^ D[0] ^ C[7] ^ C[6] ^ D[1]);

assign 			  CN[1] 	  = C[1] ^ D[0] ^ C[7] ^ D[6] ^ D[7] ^ C[0] ^ D[0] ^ C[7] ^ D[1] ^ C[6];
// assign 			  CN[1] 	  = (C[1] ^ D[0] ^ D[6] ^ (D[7] ^ C[0] ^ D[0] ^ C[7] ^ D[1] ^ C[6]);
// assign 			  CN[1] 	  = (C[1] ^ D[0] ^ D[6]  ^ D[7] ^ C[0] ^ C[7])^  D[0] ^ C[6] ^ D[1]);
assign 			  CN[0] 	  = (C[0] ^ D[0] ^ C[7] ^ D[1] ^ C[6]) ^ D[7];
// assign 			  CN[0] 	  = (C[0] ^ D[0] ^ C[7] ^ D[1] ^ C[6]) ^ D[7];
  //D[0] ^ D[1] ^ D[7] ^ C[0] ^ C[6] ^ C[7];

always @ (posedge clk or posedge reset)
begin
  if (reset)
	C <= 8'h00;
  else
	if(init)
	  C <= 8'h00;
	else
	  C <= CN;
end

// assign CrcErr = Crc[31:0] != 32'hc704dd7b;  // CRC not equal to magic number
assign 			  CrcErr 	  = Crc != 8'h00;
assign 			  PreCrcErr   = CN != 8'h00;
// //for debug
// always @ (posedge clk)
// begin
//   if(enable)
// 	$display("%t: Data = %x, Crc = %x", $time, Data, Crc);	
// end

endmodule
